昨天我們已經把Library 所設定的variable group 都推到hosted pipeline 去變成環境變數了。這時候正常的思維大概就是,我們要把我們要替換掉的secret用類似pattern 的方式替代掉,看是用script的方式去把環境變數的值抓下來,然後把他替換掉。
這時候,就要來介紹一下marketplace了(現在說好像有一點點晚了)。之前在Day 12展示pipeline的時候有用到一個套件,很感謝我的導師告訴我應該要說明一下那是一個套件,所以我趕快去補正了之前的文章。
如果你已經有Azure DevOps ,你可以在下圖的地方點選按紐,就可以把你導到marketplace。
這個marketplace裡面有非常豐富的生態圈,目前來說筆者也只有做了一些小部分的應用,後面會再根據任務來說一些其他的套件。
這次為了要完成這個環境變數去替代掉web.config的對應參數,我選擇了一個套件叫做 Replace Tokens,這個套件之前上課的時候感覺滿好用的,特別把他筆記下來。
記得,如果要使用他,請記得要先安裝才可以使用,安裝方式也很簡單,就是在marketplace給他安裝下去,他就會導頁到讓你選擇要裝在哪一個Azure DevOps Service 的organization中(當然要有權限就是了)。
原本在上課的時候是使用classic mode的方式在建立pipeline的,但現在沒辦法,只能自己去K他的yaml寫法,最後這次的寫法如下:
- task: qetza.replacetokens.replacetokens-task.replacetokens@5
displayName: '替換connectionstring in web.config'
inputs:
targetFiles: '$(Build.ArtifactStagingDirectory)\mysite\web.config'
再來就是要把我們web.config進行改造的作業,我們來k一下文件,會發現到他預設是用 #{variable_name#} 來進行替代的。
那我們就來把Web.config改造一下如下:
<connectionStrings>
<add name="InsDBCon" connectionString="Data Source=#{Data Source}#;Initial Catalog=#{Catalog}#;User Id=#{User Id}#;Password=#{Password}#;Connect Timeout=90;Connect Timeout=3000;Pooling=true;" />
</connectionStrings>
既然我們的pipeline yaml跟sourcecode的web.config都準備好了,就讓我們來執行pipeline吧!pipeline執行過程中我們可以看到這個套件有發生作用了,如下:
那由於我是把step安插在編譯後的產物之前,直接到產物去變更裡面的web.config其中的connectionstring,就讓我們下載解開來看看最終的成果。
可以看到pipeline artifact 裡面的檔案解開來,已經幫我們都置換回去了。這個方式非常棒,因為未來只要不同的環境,就建一組variable group去對應。因此在我們的環境中,可以預想到develop就是測試環境,然後main舊式營運環境。並且,除了資料庫的相關資訊以外,也可以放各種節點或是資源,例如smtp、ldap、nas或是其他api等等。
公司有一個內規,就是存在伺服器中的密碼必須要加密。其實基於資訊安全的理由,其實密碼明碼存放的確是有問題。那.net framework一直都有一個default最簡單的作法,那就是用aspnet_regiis.exe 的方式,用作業系統層級的方式去做加密的動作。這意思是,當你的web.config被部署到你伺服器之後,透過有安裝的aspnet_regiis.exe這個.net framework的預設工具,將相關加解密金鑰存在作業系統保護的位置來進行加解密。
這種做法簡單方便,加解密指令如下:
加密
C:\windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pef connectionStrings C:\inetpub\wwwroot -prov DataProtectionConfigurationProvider
解密
C:\windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pdf connectionStrings C:\inetpub\wwwroot
那我們就在cd的階段,在部署好之後,透過執行這個指令幫我們的web.config進行加密,這樣就可以達到公司的要求,同時間開發人員也不用煩惱自己要去加密這個動作了。而且未來,ci好的那整包artifact在每次cd都會全部更新,因此這個動作勢必要自動化。
那我就將cd 的yaml檔案,在 task: IISWebAppDeploymentOnMachineGroup@0 後面增加了下面的step。
- task: CmdLine@2
displayName: 'Encrypt web.config'
inputs:
script: 'C:\windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pef connectionStrings %SystemDrive%\inetpub\wwwroot\$(site) -prov DataProtectionConfigurationProvider'
最後伺服器上我們去指定的目錄解開,就可以看到web.config被加密起來了。
那當然,上面這個加密的方法,有些路徑是寫成絕對路徑的,這做法其實不見得很好,未來或許可以找到其他方法調整,就先這樣進行了。
營運環境的交付要確認的事項非常的多~